Set up
suppressPackageStartupMessages({
library(tidyverse)
})
Read in data and process
pbta_df <- readr::read_tsv(pbta_file, guess_max = 100000, show_col_types = FALSE) %>%
select(Kids_First_Participant_ID, Kids_First_Biospecimen_ID, cg_multiple, cg_id, cgGFAC, tumor_descriptor)
tmb_vaf_df <- readr::read_tsv(tmb_vaf_file, guess_max = 100000, show_col_types = FALSE) %>%
filter(!tmb >= 10) %>%
select(Kids_First_Biospecimen_ID, Variant_Classification, gene_protein, mutation_count, region_size, tmb, VAF)
genomic_paired_df <- readr::read_tsv(genomic_paired_file, guess_max = 100000, show_col_types = FALSE) %>%
left_join(pbta_df, by = c("Kids_First_Participant_ID")) %>%
left_join(tmb_vaf_df, by = c("Kids_First_Biospecimen_ID")) %>%
filter(!is.na(tmb))
# Attention as some bs specimen might not have TMB!
# If that happens, we will end up with samples lacking timepoints.
# Which patient samples don't have TMB?
# genomic_paired_df %>%
# filter(is.na(tmb)) %>%
# unique() %>%
# regulartable() %>%
# fontsize(size = 12, part = "all")
descriptors_df <- genomic_paired_df %>%
group_by(Kids_First_Participant_ID) %>%
summarize(descriptors = paste(sort(tumor_descriptor), collapse = ", "),)
# Vector to order timepoints
timepoints <- c("Diagnosis", "Progressive", "Recurrence", "Deceased", "Second Malignancy", "Unavailable")
df <- genomic_paired_df %>%
left_join(descriptors_df, by = c("Kids_First_Participant_ID", "descriptors")) %>%
mutate(td_cgGFAC = case_when(grepl("Deceased", tumor_descriptor) ~ "xDeceased",
TRUE ~ tumor_descriptor),
log10_tmb = abs(log10(tmb)),
cg_id_kids = paste(cg_id, Kids_First_Participant_ID, sep = "_"),
cg_id_kids = str_replace(cg_id_kids, "/", "_"),
cg_id_kids = str_replace(cg_id_kids, "-", "_"),
cg_id_kids = str_replace_all(cg_id_kids, " ", "_"))
# Let's count #samples per cancer groups and timepoints.
# We will use the cg_id col that indicates cancer type as identified at the first diagnostic sample
timepoint_cg_n_df <- df %>%
count(cg_id, tumor_descriptor) %>%
dplyr::mutate(timepoint_cg_n = glue::glue("{cg_id}_{tumor_descriptor} (N={n})")) %>%
dplyr::rename(timepoint_cg_number = n)
# Let's count number of samples per cancer groups and timepoints
timepoint_cgGFAC_n_df <- df %>%
count(cgGFAC, td_cgGFAC) %>%
dplyr::mutate(timepoint_cgGFAC_n = glue::glue("{cgGFAC}_{td_cgGFAC} (N={n})")) %>%
dplyr::rename(timepoint_cgGFAC_number = n)
# Create df to use for plots
df_plot <- df %>%
left_join(timepoint_cg_n_df, by = c("tumor_descriptor", "cg_id")) %>%
left_join(timepoint_cgGFAC_n_df, by = c("td_cgGFAC", "cgGFAC")) %>%
filter(!timepoint_cg_n <= 2,
!timepoint_cgGFAC_n <= 2,
!cg_id == "NA") %>%
mutate(tumor_descriptor = factor(tumor_descriptor),
tumor_descriptor = fct_relevel(tumor_descriptor, timepoints))
# Let's count number of samples
count_df <- df_plot %>%
group_by(tumor_descriptor, cg_id, Kids_First_Biospecimen_ID, Variant_Classification) %>%
dplyr::count(cg_id)
#count_df <- df_plot %>%
# dplyr::count(cg_id) %>%
# mutate(pct = n / sum(n) * 100)
Define parameters for plots
# Read color palette
palette_df <- readr::read_tsv(palette_file, guess_max = 100000, show_col_types = FALSE)
# Define and order palette
palette <- palette_df$hex_codes
names(palette) <- palette_df$color_names
Alterations per timepoint
# Define parameters for function
x_value <- count_df$tumor_descriptor
title <- paste("Variant types in PBTA cohort", sep = " ")
# Run function
fname <- paste0(plots_dir, "/", "Alteration_type_timepoints_barplots.pdf")
print(fname)
[1] "/Users/chronia/CHOP/GitHub/pbta-tumor-evolution/analyses/tmb-vaf-longitudinal/plots/Alteration_type_timepoints_barplots.pdf"
p <- create_stacked_barplot_variant(count_df = count_df, x = x_value, palette = palette, title = title)
pdf(file = fname, width = 6, height = 6)
print(p)
dev.off()
quartz_off_screen
2

Alterations per timepoint in each cancer type
cg_id_id <- as.character(unique(count_df$cg_id))
cg_id_id <- sort(cg_id_id, decreasing = FALSE)
cg_id_id
[1] "Adamantinomatous Craniopharyngioma" "Atypical Teratoid Rhabdoid Tumor" "Chordoma"
[4] "Choroid plexus carcinoma" "CNS Embryonal tumor" "Craniopharyngioma"
[7] "Diffuse midline glioma" "Dysembryoplastic neuroepithelial tumor" "Embryonal tumor with multilayer rosettes"
[10] "Ependymoma" "Ewing sarcoma" "Ganglioglioma"
[13] "Glial-neuronal tumor" "Hemangioblastoma" "High-grade glioma"
[16] "Low-grade glioma" "Malignant peripheral nerve sheath tumor" "Medulloblastoma"
[19] "Meningioma" "Neuroblastoma" "Neurofibroma/Plexiform"
[22] "Pilocytic astrocytoma" "Rosai-Dorfman disease" "Schwannoma"
# Loop through variable
for (i in seq_along(cg_id_id)){
print(i)
df_sub <- count_df %>%
filter(cg_id == cg_id_id[i])
# Define parameters for function
x_value <- df_sub$Kids_First_Biospecimen_ID
title <- paste(cg_id_id[i])
# Run function
p <- create_stacked_barplot_variant(count_df = df_sub, x = x_value, palette = palette, title = title)
}
[1] 1
[1] 2
[1] 3
[1] 4
[1] 5
[1] 6
[1] 7
[1] 8
[1] 9
[1] 10
[1] 11
[1] 12
[1] 13
[1] 14
[1] 15
[1] 16
[1] 17
[1] 18
[1] 19
[1] 20
[1] 21
[1] 22
[1] 23
[1] 24
























Alterations per timepoint in each cancer type defined by cgGFAC
# Loop through variable
for (i in seq_along(cgGFAC_id)){
print(i)
df_sub <- df_plot_cgGFAC %>%
filter(cgGFAC == cgGFAC_id[i])
# Define parameters for function
x_value <- df_sub$Kids_First_Biospecimen_ID
title <- paste(cgGFAC_id[i])
# Run function
p <- create_stacked_barplot_variant(count_df = df_sub, x = x_value, palette = palette, title = title)
}
[1] 1
[1] 2
[1] 3
[1] 4
[1] 5





Alterations per timepoint in each cancer type and timepoint
model
tm_df_plot <- df_plot %>%
filter(!is.na(timepoints_models)) %>%
group_by(tumor_descriptor, cg_id, timepoints_models, Kids_First_Biospecimen_ID, Variant_Classification) %>%
dplyr::count(timepoint_cgGFAC_n)
tm <- as.character(unique(tm_df_plot$timepoints_models))
tm <- sort(tm, decreasing = FALSE)
tm
[1] "Dx-Dec" "Dx-Pro" "Dx-Pro-Dec" "Dx-Pro-Rec" "Dx-Pro-Rec-Dec" "Dx-Rec"
[7] "Dx-Rec-Dec" "Dx-SM" "Pro-Dec" "Pro-Rec" "Pro-Rec-Dec" "Rec-Dec"
[13] "Rec-SM"
# Loop through variable
for (i in seq_along(tm)){
print(i)
df_sub <- tm_df_plot %>%
filter(timepoints_models == tm[i])
# Define parameters for function
x_value <- df_sub$Kids_First_Biospecimen_ID
title <- paste(tm[i])
# Run function
p <- create_stacked_barplot_variant_cg_id(count_df = df_sub, x = x_value, palette = palette, title = title)
}
[1] 1
[1] 2
[1] 3
[1] 4
[1] 5
[1] 6
[1] 7
[1] 8
[1] 9
[1] 10
[1] 11
[1] 12
[1] 13













sessionInfo()
R version 4.2.3 (2023-03-15)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Ventura 13.5.2
Matrix products: default
LAPACK: /Library/Frameworks/R.framework/Versions/4.2-arm64/Resources/lib/libRlapack.dylib
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
attached base packages:
[1] grid stats graphics grDevices utils datasets methods base
other attached packages:
[1] ggthemes_4.2.4 lubridate_1.9.2 forcats_1.0.0 stringr_1.5.0 dplyr_1.1.2 purrr_1.0.1 readr_2.1.4 tidyr_1.3.0 tibble_3.2.1
[10] ggplot2_3.4.2 tidyverse_2.0.0
loaded via a namespace (and not attached):
[1] tidyselect_1.2.0 xfun_0.39 bslib_0.5.0 carData_3.0-5 colorspace_2.1-0 vctrs_0.6.3 generics_0.1.3 htmltools_0.5.5
[9] yaml_2.3.7 utf8_1.2.3 rlang_1.1.1 pillar_1.9.0 jquerylib_0.1.4 ggpubr_0.6.0 glue_1.6.2 withr_2.5.0
[17] bit64_4.0.5 lifecycle_1.0.3 munsell_0.5.0 ggsignif_0.6.4 gtable_0.3.3 ragg_1.2.5 evaluate_0.21 labeling_0.4.2
[25] knitr_1.43 tzdb_0.4.0 fastmap_1.1.1 parallel_4.2.3 fansi_1.0.4 broom_1.0.5 scales_1.2.1 backports_1.4.1
[33] cachem_1.0.8 vroom_1.6.3 jsonlite_1.8.7 abind_1.4-5 systemfonts_1.0.4 farver_2.1.1 bit_4.0.5 textshaping_0.3.6
[41] hms_1.1.3 digest_0.6.33 stringi_1.7.12 rstatix_0.7.2 rprojroot_2.0.3 cli_3.6.1 tools_4.2.3 magrittr_2.0.3
[49] sass_0.4.7 crayon_1.5.2 car_3.1-2 pkgconfig_2.0.3 timechange_0.2.0 rmarkdown_2.23 rstudioapi_0.15.0 R6_2.5.1
[57] compiler_4.2.3
LS0tCnRpdGxlOiAiQ2xhc3NpZmljYXRpb24gb2YgVmFyaWFudHMgYWNyb3NzIHBhaXJlZCBsb25naXR1ZGluYWwgc2FtcGxlcyBpbiB0aGUgUEJUQSBDb2hvcnQiCmF1dGhvcjogJ0FudG9uaWEgQ2hyb25pIDxjaHJvbmlhQGNob3AuZWR1PiBmb3IgRDNCJwpkYXRlOiAiMjAyMyIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IFRSVUUKICAgIHRvY19mbG9hdDogVFJVRQotLS0KCiMgU2V0IHVwCmBgYHtyIGxvYWQtbGlicmFyeX0Kc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKHsKICBsaWJyYXJ5KHRpZHl2ZXJzZSkKfSkKYGBgCgojIERpcmVjdG9yaWVzIGFuZCBGaWxlIElucHV0cy9PdXRwdXRzCmBgYHtyIHNldC1kaXItYW5kLWZpbGUtbmFtZXN9CiMgRGV0ZWN0IHRoZSAiLmdpdCIgZm9sZGVyIC0tIHRoaXMgd2lsbCBiZSBpbiB0aGUgcHJvamVjdCByb290IGRpcmVjdG9yeQojIFVzZSB0aGlzIGFzIHRoZSByb290IGRpcmVjdG9yeSB0byBlbnN1cmUgcHJvcGVyIHNvdXJjaW5nIG9mIGZ1bmN0aW9ucyAKIyBubyBtYXR0ZXIgd2hlcmUgdGhpcyBpcyBjYWxsZWQgZnJvbQpyb290X2RpciA8LSBycHJvanJvb3Q6OmZpbmRfcm9vdChycHJvanJvb3Q6Omhhc19kaXIoIi5naXQiKSkKYW5hbHlzaXNfZGlyIDwtIGZpbGUucGF0aChyb290X2RpciwgImFuYWx5c2VzIiwgInRtYi12YWYtbG9uZ2l0dWRpbmFsIikKcmVzdWx0c19kaXIgPC0gZmlsZS5wYXRoKGFuYWx5c2lzX2RpciwgInJlc3VsdHMiKQppbnB1dF9kaXIgPC0gZmlsZS5wYXRoKGFuYWx5c2lzX2RpciwgImlucHV0IikKZmlsZXNfZGlyIDwtIGZpbGUucGF0aChyb290X2RpciwgImFuYWx5c2VzIiwgInNhbXBsZS1kaXN0cmlidXRpb24tYW5hbHlzaXMiLCAicmVzdWx0cyIpCgojIElucHV0IGZpbGVzCnBidGFfZmlsZSA8LSBmaWxlLnBhdGgoZmlsZXNfZGlyLCAicGJ0YS50c3YiKSAjIGZpbGUgZnJvbSBhZGQtc2FtcGxlLWRpc3RyaWJ1dGlvbiBtb2R1bGUKZ2Vub21pY19wYWlyZWRfZmlsZSA8LSBmaWxlLnBhdGgoZmlsZXNfZGlyLCAiZ2Vub21pY19hc3NheXNfbWF0Y2hlZF90aW1lX3BvaW50cy50c3YiKQp0bWJfdmFmX2ZpbGUgPC0gZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAidG1iX3ZhZl9nZW5vbWljLnRzdiIpCnBhbGV0dGVfZmlsZSA8LSBmaWxlLnBhdGgocm9vdF9kaXIsICJmaWd1cmVzIiwgInBhbGV0dGVzIiwgIm9uY29wcmludF9jb2xvcl9wYWxldHRlLnRzdiIpCgojIEZpbGUgcGF0aCB0byBwbG90IGRpcmVjdG9yeQpwbG90c19kaXIgPC0KICBmaWxlLnBhdGgoYW5hbHlzaXNfZGlyLCAicGxvdHMiKQppZiAoIWRpci5leGlzdHMocGxvdHNfZGlyKSkgewogIGRpci5jcmVhdGUocGxvdHNfZGlyKQp9Cgpzb3VyY2UocGFzdGUwKHJvb3RfZGlyLCAiL2ZpZ3VyZXMvc2NyaXB0cy90aGVtZS5SIikpCnNvdXJjZShwYXN0ZTAoYW5hbHlzaXNfZGlyLCAiL3V0aWwvZnVuY3Rpb24tY3JlYXRlLWJhcnBsb3QuUiIpKQpgYGAKCiMgUmVhZCBpbiBkYXRhIGFuZCBwcm9jZXNzCgpgYGB7ciBsb2FkLXByb2Nlc3MtaW5wdXRzfQpwYnRhX2RmIDwtIHJlYWRyOjpyZWFkX3RzdihwYnRhX2ZpbGUsIGd1ZXNzX21heCA9IDEwMDAwMCwgc2hvd19jb2xfdHlwZXMgPSBGQUxTRSkgJT4lIAogIHNlbGVjdChLaWRzX0ZpcnN0X1BhcnRpY2lwYW50X0lELCBLaWRzX0ZpcnN0X0Jpb3NwZWNpbWVuX0lELCBjZ19tdWx0aXBsZSwgY2dfaWQsIGNnR0ZBQywgdHVtb3JfZGVzY3JpcHRvcikKCnRtYl92YWZfZGYgPC0gcmVhZHI6OnJlYWRfdHN2KHRtYl92YWZfZmlsZSwgZ3Vlc3NfbWF4ID0gMTAwMDAwLCBzaG93X2NvbF90eXBlcyA9IEZBTFNFKSAlPiUgCiAgZmlsdGVyKCF0bWIgPj0gMTApICU+JSAKICBzZWxlY3QoS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCwgVmFyaWFudF9DbGFzc2lmaWNhdGlvbiwgZ2VuZV9wcm90ZWluLCBtdXRhdGlvbl9jb3VudCwJcmVnaW9uX3NpemUsIHRtYiwgVkFGKQoKZ2Vub21pY19wYWlyZWRfZGYgPC0gcmVhZHI6OnJlYWRfdHN2KGdlbm9taWNfcGFpcmVkX2ZpbGUsIGd1ZXNzX21heCA9IDEwMDAwMCwgc2hvd19jb2xfdHlwZXMgPSBGQUxTRSkgJT4lCiAgbGVmdF9qb2luKHBidGFfZGYsIGJ5ID0gYygiS2lkc19GaXJzdF9QYXJ0aWNpcGFudF9JRCIpKSAlPiUgCiAgbGVmdF9qb2luKHRtYl92YWZfZGYsIGJ5ID0gYygiS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCIpKSAlPiUKICBmaWx0ZXIoIWlzLm5hKHRtYikpCgojIEF0dGVudGlvbiBhcyBzb21lIGJzIHNwZWNpbWVuIG1pZ2h0IG5vdCBoYXZlIFRNQiEKIyBJZiB0aGF0IGhhcHBlbnMsIHdlIHdpbGwgZW5kIHVwIHdpdGggc2FtcGxlcyBsYWNraW5nIHRpbWVwb2ludHMuCgojIFdoaWNoIHBhdGllbnQgc2FtcGxlcyBkb24ndCBoYXZlIFRNQj8KIyBnZW5vbWljX3BhaXJlZF9kZiAlPiUgCiMgIGZpbHRlcihpcy5uYSh0bWIpKSAlPiUgCiMgIHVuaXF1ZSgpICU+JSAKIyAgcmVndWxhcnRhYmxlKCkgJT4lCiMgIGZvbnRzaXplKHNpemUgPSAxMiwgcGFydCA9ICJhbGwiKQoKZGVzY3JpcHRvcnNfZGYgPC0gZ2Vub21pY19wYWlyZWRfZGYgJT4lCiAgZ3JvdXBfYnkoS2lkc19GaXJzdF9QYXJ0aWNpcGFudF9JRCkgJT4lCiAgc3VtbWFyaXplKGRlc2NyaXB0b3JzID0gcGFzdGUoc29ydCh0dW1vcl9kZXNjcmlwdG9yKSwgY29sbGFwc2UgPSAiLCAiKSwpIAoKIyBWZWN0b3IgdG8gb3JkZXIgdGltZXBvaW50cwp0aW1lcG9pbnRzIDwtIGMoIkRpYWdub3NpcyIsICJQcm9ncmVzc2l2ZSIsICJSZWN1cnJlbmNlIiwgIkRlY2Vhc2VkIiwgIlNlY29uZCBNYWxpZ25hbmN5IiwgIlVuYXZhaWxhYmxlIikKCmRmIDwtIGdlbm9taWNfcGFpcmVkX2RmICU+JSAKICBsZWZ0X2pvaW4oZGVzY3JpcHRvcnNfZGYsIGJ5ID0gYygiS2lkc19GaXJzdF9QYXJ0aWNpcGFudF9JRCIsICJkZXNjcmlwdG9ycyIpKSAlPiUgCiAgbXV0YXRlKHRkX2NnR0ZBQyA9IGNhc2Vfd2hlbihncmVwbCgiRGVjZWFzZWQiLCB0dW1vcl9kZXNjcmlwdG9yKSB+ICJ4RGVjZWFzZWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSB+IHR1bW9yX2Rlc2NyaXB0b3IpLAogICAgICAgICBsb2cxMF90bWIgPSBhYnMobG9nMTAodG1iKSksCiAgICAgICAgIGNnX2lkX2tpZHMgPSBwYXN0ZShjZ19pZCwgS2lkc19GaXJzdF9QYXJ0aWNpcGFudF9JRCwgc2VwID0gIl8iKSwKICAgICAgICAgY2dfaWRfa2lkcyA9IHN0cl9yZXBsYWNlKGNnX2lkX2tpZHMsICIvIiwgIl8iKSwKICAgICAgICAgY2dfaWRfa2lkcyA9IHN0cl9yZXBsYWNlKGNnX2lkX2tpZHMsICItIiwgIl8iKSwKICAgICAgICAgY2dfaWRfa2lkcyA9IHN0cl9yZXBsYWNlX2FsbChjZ19pZF9raWRzLCAiICIsICJfIikpCgojIExldCdzIGNvdW50ICNzYW1wbGVzIHBlciBjYW5jZXIgZ3JvdXBzIGFuZCB0aW1lcG9pbnRzLgojIFdlIHdpbGwgdXNlIHRoZSBjZ19pZCBjb2wgdGhhdCBpbmRpY2F0ZXMgY2FuY2VyIHR5cGUgYXMgaWRlbnRpZmllZCBhdCB0aGUgZmlyc3QgZGlhZ25vc3RpYyBzYW1wbGUKdGltZXBvaW50X2NnX25fZGYgPC0gZGYgJT4lIAogIGNvdW50KGNnX2lkLCB0dW1vcl9kZXNjcmlwdG9yKSAlPiUgCiAgZHBseXI6Om11dGF0ZSh0aW1lcG9pbnRfY2dfbiA9IGdsdWU6OmdsdWUoIntjZ19pZH1fe3R1bW9yX2Rlc2NyaXB0b3J9ICAoTj17bn0pIikpICU+JSAKICBkcGx5cjo6cmVuYW1lKHRpbWVwb2ludF9jZ19udW1iZXIgPSBuKSAKCiMgTGV0J3MgY291bnQgbnVtYmVyIG9mIHNhbXBsZXMgcGVyIGNhbmNlciBncm91cHMgYW5kIHRpbWVwb2ludHMgCnRpbWVwb2ludF9jZ0dGQUNfbl9kZiA8LSBkZiAlPiUgCiAgY291bnQoY2dHRkFDLCB0ZF9jZ0dGQUMpICU+JSAKICBkcGx5cjo6bXV0YXRlKHRpbWVwb2ludF9jZ0dGQUNfbiA9IGdsdWU6OmdsdWUoIntjZ0dGQUN9X3t0ZF9jZ0dGQUN9ICAoTj17bn0pIikpICU+JSAKICBkcGx5cjo6cmVuYW1lKHRpbWVwb2ludF9jZ0dGQUNfbnVtYmVyID0gbikgCgojIENyZWF0ZSBkZiB0byB1c2UgZm9yIHBsb3RzCmRmX3Bsb3QgPC0gZGYgJT4lIAogIGxlZnRfam9pbih0aW1lcG9pbnRfY2dfbl9kZiwgYnkgPSBjKCJ0dW1vcl9kZXNjcmlwdG9yIiwgImNnX2lkIikpICU+JQogIGxlZnRfam9pbih0aW1lcG9pbnRfY2dHRkFDX25fZGYsIGJ5ID0gYygidGRfY2dHRkFDIiwgImNnR0ZBQyIpKSAlPiUgCiAgZmlsdGVyKCF0aW1lcG9pbnRfY2dfbiA8PSAyLAogICAgICAgICAhdGltZXBvaW50X2NnR0ZBQ19uIDw9IDIsCiAgICAgICAgICFjZ19pZCA9PSAiTkEiKSAlPiUgCiAgbXV0YXRlKHR1bW9yX2Rlc2NyaXB0b3IgPSBmYWN0b3IodHVtb3JfZGVzY3JpcHRvciksCiAgICAgICAgIHR1bW9yX2Rlc2NyaXB0b3IgPSBmY3RfcmVsZXZlbCh0dW1vcl9kZXNjcmlwdG9yLCB0aW1lcG9pbnRzKSkKCiMgTGV0J3MgY291bnQgbnVtYmVyIG9mIHNhbXBsZXMgCmNvdW50X2RmIDwtIGRmX3Bsb3QgJT4lIAogIGdyb3VwX2J5KHR1bW9yX2Rlc2NyaXB0b3IsIGNnX2lkLCBLaWRzX0ZpcnN0X0Jpb3NwZWNpbWVuX0lELCBWYXJpYW50X0NsYXNzaWZpY2F0aW9uKSAlPiUgCiAgZHBseXI6OmNvdW50KGNnX2lkKSAKCiNjb3VudF9kZiA8LSBkZl9wbG90ICU+JSAKIyAgZHBseXI6OmNvdW50KGNnX2lkKSAlPiUgCiMgIG11dGF0ZShwY3QgPSBuIC8gc3VtKG4pICogMTAwKQpgYGAgCgojIERlZmluZSBwYXJhbWV0ZXJzIGZvciBwbG90cwoKYGBge3IgZGVmaW5lLXBhcmFtZXRlcnMtZm9yLXBsb3RzfQojIFJlYWQgY29sb3IgcGFsZXR0ZQpwYWxldHRlX2RmIDwtIHJlYWRyOjpyZWFkX3RzdihwYWxldHRlX2ZpbGUsIGd1ZXNzX21heCA9IDEwMDAwMCwgc2hvd19jb2xfdHlwZXMgPSBGQUxTRSkgCgojIERlZmluZSBhbmQgb3JkZXIgcGFsZXR0ZQpwYWxldHRlIDwtIHBhbGV0dGVfZGYkaGV4X2NvZGVzCm5hbWVzKHBhbGV0dGUpIDwtIHBhbGV0dGVfZGYkY29sb3JfbmFtZXMKCmBgYAoKIyBBbHRlcmF0aW9ucyBwZXIgdGltZXBvaW50CgpgYGB7ciBwbG90LXRpbWVwb2ludCwgZmlnLndpZHRoID0gNiwgZmlnLmhlaWdodCA9IDYsIGZpZy5mdWxsd2lkdGggPSBUUlVFfQojIERlZmluZSBwYXJhbWV0ZXJzIGZvciBmdW5jdGlvbgp4X3ZhbHVlIDwtIGNvdW50X2RmJHR1bW9yX2Rlc2NyaXB0b3IKdGl0bGUgPC0gcGFzdGUoIlZhcmlhbnQgdHlwZXMgaW4gUEJUQSBjb2hvcnQiLCBzZXAgPSAiICIpCgojIFJ1biBmdW5jdGlvbgpmbmFtZSA8LSBwYXN0ZTAocGxvdHNfZGlyLCAiLyIsICJBbHRlcmF0aW9uX3R5cGVfdGltZXBvaW50c19iYXJwbG90cy5wZGYiKQpwcmludChmbmFtZSkKcCA8LSBjcmVhdGVfc3RhY2tlZF9iYXJwbG90X3ZhcmlhbnQoY291bnRfZGYgPSBjb3VudF9kZiwgeCA9IHhfdmFsdWUsIHBhbGV0dGUgPSBwYWxldHRlLCB0aXRsZSA9IHRpdGxlKQpwZGYoZmlsZSA9IGZuYW1lLCB3aWR0aCA9IDYsIGhlaWdodCA9IDYpCnByaW50KHApCmRldi5vZmYoKQpgYGAKCiMgQWx0ZXJhdGlvbnMgcGVyIHRpbWVwb2ludCBpbiBlYWNoIGNhbmNlciB0eXBlCgpgYGB7ciBwbG90LWNnLWlkLCBmaWcud2lkdGggPSA1LCBmaWcuaGVpZ2h0ID0gNSwgZmlnLmZ1bGx3aWR0aCA9IFRSVUV9CmNnX2lkX2lkIDwtIGFzLmNoYXJhY3Rlcih1bmlxdWUoY291bnRfZGYkY2dfaWQpKSAKY2dfaWRfaWQgPC0gc29ydChjZ19pZF9pZCwgZGVjcmVhc2luZyA9IEZBTFNFKQpjZ19pZF9pZAoKIyBMb29wIHRocm91Z2ggdmFyaWFibGUKZm9yIChpIGluIHNlcV9hbG9uZyhjZ19pZF9pZCkpewogIHByaW50KGkpCiAgZGZfc3ViIDwtIGNvdW50X2RmICU+JQogICAgICBmaWx0ZXIoY2dfaWQgPT0gY2dfaWRfaWRbaV0pCiAgCiAgIyBEZWZpbmUgcGFyYW1ldGVycyBmb3IgZnVuY3Rpb24KICB4X3ZhbHVlIDwtIGRmX3N1YiRLaWRzX0ZpcnN0X0Jpb3NwZWNpbWVuX0lECiAgdGl0bGUgPC0gcGFzdGUoY2dfaWRfaWRbaV0pCiAgCiAgIyBSdW4gZnVuY3Rpb24KICBwIDwtIGNyZWF0ZV9zdGFja2VkX2JhcnBsb3RfdmFyaWFudChjb3VudF9kZiA9IGRmX3N1YiwgeCA9IHhfdmFsdWUsIHBhbGV0dGUgPSBwYWxldHRlLCB0aXRsZSA9IHRpdGxlKQoKfQoKYGBgCgojIEFsdGVyYXRpb25zIHBlciB0aW1lcG9pbnQgaW4gZWFjaCBjYW5jZXIgdHlwZSBkZWZpbmVkIGJ5IGNnR0ZBQwoKYGBge3IgcGxvdC1jZ0dGQUMtbi1pbmRpdmlkdWFsLXBsb3RzLCBmaWcud2lkdGggPSA1LCBmaWcuaGVpZ2h0ID0gNSwgZmlnLmZ1bGx3aWR0aCA9IFRSVUV9CmRmX3Bsb3RfY2dHRkFDIDwtIGRmX3Bsb3QgJT4lCiAgZmlsdGVyKCFpcy5uYSh0aW1lcG9pbnRzX21vZGVscykpICU+JSAKICBhcnJhbmdlKHRpbWVwb2ludF9jZ0dGQUNfbikgJT4lIAogIGdyb3VwX2J5KHR1bW9yX2Rlc2NyaXB0b3IsIGNnR0ZBQywgdGltZXBvaW50X2NnR0ZBQ19uLCBLaWRzX0ZpcnN0X0Jpb3NwZWNpbWVuX0lELCBWYXJpYW50X0NsYXNzaWZpY2F0aW9uKSAlPiUgCiAgZHBseXI6OmNvdW50KHRpbWVwb2ludF9jZ0dGQUNfbikKCmNnR0ZBQ19pZCA8LSBhcy5jaGFyYWN0ZXIodW5pcXVlKGRmX3Bsb3RfY2dHRkFDJGNnR0ZBQykpIApjZ0dGQUNfaWQgPC0gc29ydChjZ0dGQUNfaWQsIGRlY3JlYXNpbmcgPSBGQUxTRSkKY2dHRkFDX2lkCgojIExvb3AgdGhyb3VnaCB2YXJpYWJsZQpmb3IgKGkgaW4gc2VxX2Fsb25nKGNnR0ZBQ19pZCkpewogIHByaW50KGkpCiAgZGZfc3ViIDwtIGRmX3Bsb3RfY2dHRkFDICU+JQogICAgICBmaWx0ZXIoY2dHRkFDID09IGNnR0ZBQ19pZFtpXSkKICAKICAjIERlZmluZSBwYXJhbWV0ZXJzIGZvciBmdW5jdGlvbgogIHhfdmFsdWUgPC0gZGZfc3ViJEtpZHNfRmlyc3RfQmlvc3BlY2ltZW5fSUQKICB0aXRsZSA8LSBwYXN0ZShjZ0dGQUNfaWRbaV0pCiAgCiAgIyBSdW4gZnVuY3Rpb24KICBwIDwtIGNyZWF0ZV9zdGFja2VkX2JhcnBsb3RfdmFyaWFudChjb3VudF9kZiA9IGRmX3N1YiwgeCA9IHhfdmFsdWUsIHBhbGV0dGUgPSBwYWxldHRlLCB0aXRsZSA9IHRpdGxlKQoKfQpgYGAKCiMgQWx0ZXJhdGlvbnMgcGVyIHRpbWVwb2ludCBpbiBlYWNoIGNhbmNlciB0eXBlIGFuZCB0aW1lcG9pbnQgbW9kZWwKCmBgYHtyIHBsb3QtdGltZXBvaW50LW1vZGVsLCBmaWcud2lkdGggPSA4LCBmaWcuaGVpZ2h0ID0gNiwgZmlnLmZ1bGx3aWR0aCA9IFRSVUV9CnRtX2RmX3Bsb3QgPC0gZGZfcGxvdCAlPiUKICBmaWx0ZXIoIWlzLm5hKHRpbWVwb2ludHNfbW9kZWxzKSkgJT4lIAogIGdyb3VwX2J5KHR1bW9yX2Rlc2NyaXB0b3IsIGNnX2lkLCB0aW1lcG9pbnRzX21vZGVscywgS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCwgVmFyaWFudF9DbGFzc2lmaWNhdGlvbikgJT4lIAogIGRwbHlyOjpjb3VudCh0aW1lcG9pbnRfY2dHRkFDX24pCgp0bSA8LSBhcy5jaGFyYWN0ZXIodW5pcXVlKHRtX2RmX3Bsb3QkdGltZXBvaW50c19tb2RlbHMpKQp0bSA8LSBzb3J0KHRtLCBkZWNyZWFzaW5nID0gRkFMU0UpCnRtCgojIExvb3AgdGhyb3VnaCB2YXJpYWJsZQpmb3IgKGkgaW4gc2VxX2Fsb25nKHRtKSl7CiAgcHJpbnQoaSkKICBkZl9zdWIgPC0gdG1fZGZfcGxvdCAlPiUKICAgICAgZmlsdGVyKHRpbWVwb2ludHNfbW9kZWxzID09IHRtW2ldKQogIAogICAjIERlZmluZSBwYXJhbWV0ZXJzIGZvciBmdW5jdGlvbgogIHhfdmFsdWUgPC0gZGZfc3ViJEtpZHNfRmlyc3RfQmlvc3BlY2ltZW5fSUQKICB0aXRsZSA8LSBwYXN0ZSh0bVtpXSkKICAKICAjIFJ1biBmdW5jdGlvbgogIHAgPC0gY3JlYXRlX3N0YWNrZWRfYmFycGxvdF92YXJpYW50X2NnX2lkKGNvdW50X2RmID0gZGZfc3ViLCB4ID0geF92YWx1ZSwgcGFsZXR0ZSA9IHBhbGV0dGUsIHRpdGxlID0gdGl0bGUpCiAgCn0KYGBgCgoKYGBge3IgZWNobz1UUlVFfQpzZXNzaW9uSW5mbygpCmBgYAo=